package sqlToGUI.charts;


import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.swing.JTable;
import javax.swing.table.TableColumn;

import sqlToGUI.HarpalykeGUI1;
import sqlToGUI.charts.helperUtilities.ArrayPowerMapRenderer;
import sqlToGUI.charts.helperUtilities.TelemetryChartEvent;
import sqlToGUI.charts.helperUtilities.TelemetryChartListener;
import sqlToGUI.charts.helperUtilities.TelemetryDataEntry;

import java.util.Properties;


public class ArrayPowerMap implements GUIDisplay {
	
	/**The list receiving the new data from the outside -
	 * This class will be responsible for listening to this
	 * list and updating from it whenever new information
	 * is available -
	 * The array is used in case chart uses reference to more
	 * than one data set and is updated from more than one
	 * list */
	private TelemetryDataEntry [] dataEntries;
	
	/**The buffer storing the specific input for the array map */
	private double [] input;

	/**Objects allowing to render and change the colour of the map */
	private ArrayPowerMapRenderer t1Renderer, t2Renderer, t3Renderer;

	/**JFrame object storing the array map */
	private Container arrayMap;
	private Container chart;
	
	/**The number of sub=arrays this map will represent */
	private int numSubArrays;
	
	/**The tables storing the upper, mid, and lower sections of the
	 * sub-arrays */
	private JTable table1, table2, table3;

	/**Class constructor*/
	public ArrayPowerMap(){

		try {
			arrayMapProperties = new Properties();
			arrayMapProperties.load(new FileInputStream
					("properties/ArrayPowerMap.properties"));
		} catch (FileNotFoundException e) {
			System.out.println("ArrayPowerMap: Failed to read property file");
			System.exit(1);
		} catch (IOException e) {
			System.out.println("ArrayPowerMap: Failed to read property file");
			System.exit(1);
		}

		numSubArrays = Integer.parseInt(arrayMapProperties.
				getProperty("numOfSubArrays"));
		input = new double[numSubArrays];
		
		chart = new Container();
		
		createArrayMap();
	}

	/**Properties storing data about the structure of the solar array */
	private Properties arrayMapProperties;

	/**The log panel data will monitor the incoming data */
	private LogPanel log;
	/**Variable indicating whether or not a log has been
	 * registered */
	private boolean logReg = false;
	
	/**Method for creating the array-map */
	public void createArrayMap(){

		/**Initialize the map and its' tables */
		arrayMap =  new Container();
		arrayMap.setLayout(new BorderLayout());

		table1 = new JTable(1, 5);
		table2 = new JTable(1, 3);
		table3 = new JTable(1, 4);

		table1.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		table2.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		table3.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

		table1.setRowHeight((int)(277*HarpalykeGUI1.resizer));
		table2.setRowHeight((int)(150*HarpalykeGUI1.resizer));
		table3.setRowHeight((int)(150*HarpalykeGUI1.resizer));

		/**Initialize the cell renderers*/
		t1Renderer = new ArrayPowerMapRenderer(5);
		t2Renderer = new ArrayPowerMapRenderer(3);
		t3Renderer = new ArrayPowerMapRenderer(4);

		table1.setDefaultRenderer(Object.class, t1Renderer);
		table2.setDefaultRenderer(Object.class, t2Renderer);
		table3.setDefaultRenderer(Object.class, t3Renderer);

		/**Adjust the columns to for good looking size */
		TableColumn cola1 = table1.getColumnModel().getColumn(0);
		TableColumn cola2 = table1.getColumnModel().getColumn(1);
		TableColumn cola3 = table1.getColumnModel().getColumn(2);
		TableColumn cola4 = table1.getColumnModel().getColumn(3);
		TableColumn cola5 = table1.getColumnModel().getColumn(4);

		TableColumn colb1 = table1.getColumnModel().getColumn(0);
		TableColumn colb2 = table1.getColumnModel().getColumn(1);
		TableColumn colb3= table1.getColumnModel().getColumn(2);

		TableColumn colc1 = table1.getColumnModel().getColumn(0);
		TableColumn colc2 = table1.getColumnModel().getColumn(1);
		TableColumn colc3 = table1.getColumnModel().getColumn(2);
		TableColumn colc4 = table1.getColumnModel().getColumn(3);

		cola1.setPreferredWidth((int)(20*HarpalykeGUI1.resizer));
		cola2.setPreferredWidth((int)(20*HarpalykeGUI1.resizer));
		cola3.setPreferredWidth((int)(20*HarpalykeGUI1.resizer));
		cola4.setPreferredWidth((int)(20*HarpalykeGUI1.resizer));
		cola5.setPreferredWidth((int)(20*HarpalykeGUI1.resizer));

		colb1.setPreferredWidth((int)(33*HarpalykeGUI1.resizer));
		colb2.setPreferredWidth((int)(34*HarpalykeGUI1.resizer));
		colb3.setPreferredWidth((int)(33*HarpalykeGUI1.resizer));

		colc1.setPreferredWidth((int)(25*HarpalykeGUI1.resizer));
		colc2.setPreferredWidth((int)(25*HarpalykeGUI1.resizer));
		colc3.setPreferredWidth((int)(25*HarpalykeGUI1.resizer));
		colc4.setPreferredWidth((int)(25*HarpalykeGUI1.resizer));

		arrayMap.add(table1, BorderLayout.NORTH);
		arrayMap.add(table2, BorderLayout.CENTER);
		arrayMap.add(table3, BorderLayout.SOUTH);

		double[]tt1 = {33, 38, 92, 96, 100};
		double[]tt2 = {28, 22, 17};
		double[]tt3 = {0, 3, 8, 14};

		t1Renderer.takeInput(tt1);
		t2Renderer.takeInput(tt2);
		t3Renderer.takeInput(tt3);


		table1.repaint();
		table2.repaint();
		table3.repaint();

		arrayMap.setPreferredSize(
				new Dimension((int)(250*HarpalykeGUI1.resizer), 
						(int)(577*HarpalykeGUI1.resizer)));
		
		/**Adding this to a new container so that the array map can be
		 * organized under a layout manager and be displayed nicely on
		 * the interface */
		chart.setLayout(new FlowLayout());
		chart.add(arrayMap, BorderLayout.CENTER);
		
		//chart.
		
	}

	/**Register the given log so that it can monitor incoming data */
	public GUIDisplay registerLog(LogPanel log){
		this.log = log;
		logReg = true;
		return this;
	}
	
	public void addToBuffer(int index, double value) {

	}

	/**Return the buffer for the array map */
	public TelemetryDataEntry [] getBuffers() {

			/**Create the event(update map) when this buffer receives
			 * new data */			
		    dataEntries = new TelemetryDataEntry [1];
		    dataEntries[0] = new TelemetryDataEntry(12);
		    
			dataEntries[0].addTelemetryChartEventListener(
					new TelemetryChartListener() {
						public void myEventOccurred(TelemetryChartEvent evt) {
							input = dataEntries[0].getUpdate();
							
							double[]t1 = {input[0], input[1], input[2], 
									input[3], input[4]};
							double[]t2 = {input[5], input[6], input[7]}; 
							double[]t3 = {input[8], input[9], input[10], 
									input[11]};
							t1Renderer.takeInput(t1);
							t2Renderer.takeInput(t2);
							t3Renderer.takeInput(t3);
							
							table1.repaint();
							table2.repaint();
							table3.repaint();
						}
					});
		
			/**TODO: send data to the log*/
			
		return dataEntries;
	}

	/**Return the array-map */
	public Container getChart() {
		return chart;
	}
}
